﻿<!DOCTYPE html>
<html lang="en">
<head>
    <title>Chess Visualizer - Daniel Rogers, Evan Van Dam</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
        body {
            font-family: Monospace;
            background-color: #333;
            color: #fff;
            margin: 0px;
            overflow: hidden;
        }

        #info {
            color: #fff;
            position: absolute;
            top: 10px;
            width: 100%;
            text-align: center;
            z-index: 100;
            display: block;
        }

            #info a, .button {
                color: #f00;
                font-weight: bold;
                text-decoration: underline;
                cursor: pointer;
            }
    </style>
</head>
<body>
    <div style="position: absolute; bottom: 20px; left: 20px;">
        White clock:
        <span id="whiteTime">0:00</span>
    </div>
    <div style="position: absolute; float: right; bottom: 20px; right: 20px;">
        Black clock:
        <span id="blackTime">0:00</span>
    </div>

    <script src="js/lib/Three.js"></script>
    <script src="js/lib/dat.gui.min.js"></script>
    <script src="js/lib/jquery-1.10.2.min.js"></script>

    <script src="js/loaders/MTLLoader.js"></script>
    <script src="js/loaders/OBJLoader.js"></script>
    <script src="js/loaders/OBJMTLLoader.js"></script>
    <script src="js/engine/particlefield.js"></script>
    <script src="js/engine/controller.js"></script>
    <script src="js/engine/board.js"></script> 
    <script src="js/datgui.js"></script>

    <script>
        var container, stats;
        var camera, scene, renderer;
        var view;   // for datgui

        var rad = (Math.PI / 180);
        // control camera movement by clicking and dragging
        var mouseEnabled = false;
        var startX, startY;
        var mouseX, mouseY;
        var isClicked = false; 

        // track if we are in the process of rotating to a side
        var rotating = false, toOverhead = false, toBoardLevel = false;
        var maxY = 20, minY = -0.5;

        init();
        initDatGui();
        animate();

        // start camera movement on load - give it a sec for load times
        setTimeout(boardLevelView, 2000);

        function init() {

            container = document.createElement('div');
            document.body.appendChild(container);
            camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
            camera.position.z = -10;
            camera.position.y = 10;
            camera.position.x = 2;

            // scene
            scene = new THREE.Scene();
            var ambient = new THREE.AmbientLight(0x101010);
            scene.add(ambient);
            var directionalLight = new THREE.DirectionalLight(0xffeedd);
            directionalLight.position.set(0.5, 2, 5);
            scene.add(directionalLight);

            // add another light
            var directionalLight1 = new THREE.DirectionalLight(0xffeedd);
            directionalLight1.intensity = 1.5;
            directionalLight1.position.set(-0.5, 1, -5);
            scene.add(directionalLight1);

            var spotLight = new THREE.SpotLight(0xffffff);
            spotLight.position.set(2, 5, 1);
            scene.add(spotLight);
            
            //Get a new game controller, also builds the board
            controller = new Controller(scene);
            
            renderer = new THREE.WebGLRenderer();
            renderer.setSize(window.innerWidth, window.innerHeight);

            container.appendChild(renderer.domElement);

            window.addEventListener('resize', onWindowResize, false);
            document.addEventListener('mousemove', onDocumentMouseMove, false);
            document.addEventListener('mousedown', function (evt) {
                isClicked = true;
                startX = event.clientX;
                startY = event.clientY;
            }, false);

            document.addEventListener('mouseup', function () {
                isClicked = false;
                startX = null;
                startY = null;
            }, false);
            // scroll to zoom in or out (adjust the camera's z coordinate)
            document.addEventListener('mousewheel', function (evt) {
                if (evt.wheelDeltaY > 0)
                    camera.position.z--;
                else
                    camera.position.z++;                    
            }, false);
        }

        function cloneObj(obj) {
            var i, cpy = new THREE.Object3D();
            for (var i in obj.children) {
                cpy.add(
                    new THREE.Mesh(obj.children[i].geometry)
                );
            }
            return cpy;
        }

        function cloneObjMtl(objmtl) {
            var i, cpy = new THREE.Object3D();
            for (var i in objmtl.children) {
                cpy.add(
                    new THREE.Mesh(objmtl.children[i].geometry,
                    objmtl.children[i].material)
                );
            }
            return cpy;
        }

        function onWindowResize() {
            windowHalfX = window.innerWidth / 2;
            windowHalfY = window.innerHeight / 2;
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        }

        function onDocumentMouseMove() {
            mouseX = event.clientX;
            mouseY = event.clientY;
        }

        function animate() {
            requestAnimationFrame(animate);
            render();
        }

        // rotate 180 degrees in render function
        function rotateView() {
            // set the flag to true so it won't be interrupted
            if (!rotating) {
                rotating = true;
                controller.board.board.rotateY(rad * 2);
            }
        }

        // increment the height of the camera until birdseye view
        function overheadView() {
            if (!toOverhead && !toBoardLevel) 
                toOverhead = true;
        }

        // go back to board-level (almost)
        function boardLevelView() {
            if (!toOverhead && !toBoardLevel) {
                toBoardLevel = true;
            }
        }

        // move the camera position towards the destination by the interval
        // return true when done moving
        function moveCamera(axis, step, limit) {
            if (axis === 'Y') {
                if (camera.position.y !== limit) {
                    if (camera.position.y < limit - step)
                        camera.position.y += step;
                    else if (camera.position.y > limit + step)
                        camera.position.y -= step;
                    else {
                        camera.position.y = limit;
                    }
                    return false;
                }
                else
                    return true;
            }
            else if (axis === 'X') {
                if (camera.position.x !== limit) {
                    if (camera.position.x < limit - step)
                        camera.position.x += step;
                    else if (camera.position.x > limit + step)
                        camera.position.x -= step;
                    else {
                        camera.position.x = limit;
                    }
                    return false;
                }
                else
                    return true;
            }
            else if (axis === 'Z') {
                if (camera.position.z !== limit) {
                    if (camera.position.z < limit - step)
                        camera.position.z += step;
                    else if (camera.position.z > limit + step)
                        camera.position.z -= step;
                    else {
                        camera.position.z = limit;
                    }
                    return false;
                }
                else
                    return true;
            }
        }

        // incrementally move the camera towards (x, y, z)
        // return true when all movement is complete
        function moveCameraTo(x, y, z) {
            var xDone = moveCamera('X', 0.06, x);
            var yDone = moveCamera('Y', 0.06, y);
            var zDone = moveCamera('Z', 0.06, z);
            return xDone && yDone && zDone;
        }

        function render() {
            
            if (rotating) {
                if(controller.board.board.rotation.y <= -rad || controller.board.board.rotation.y >= rad)
                    controller.board.board.rotateY(rad);
                else
                    rotating = false;
            }

            // all of these functions either increment/decrement the position of the camera
            // and once the value is smaller than the step, it is set to the target value.
            if (toOverhead) {
                // still moving until it returns true (done)
                toOverhead = !moveCameraTo(0, 10, 8);
            }
            else if (toBoardLevel) {
                toBoardLevel = !moveCameraTo(-10, 3, 2);
            }

            if (mouseEnabled && isClicked) {
                var deltaX = mouseX - startX;
                var deltaY = mouseY - startY;
                // rotate board simulates rotating camera
                if(deltaX && !rotating)
                    controller.board.board.rotateY(rad * deltaX / 500);
                // need to actually adjust camera to avoid board getting aligned improperly
                if (deltaY && !toOverhead && !toBoardLevel) {
                    if((camera.position.y < maxY && deltaY > 0) || (camera.position.y > minY && deltaY < 0))
                        camera.position.y += deltaY / 500;
                }
            }
            camera.lookAt(scene.position);
            renderer.render(scene, camera);
            
            controller.board.animate();
        }

    </script>
</body>
</html>
